#ifndef UTILITY_FEATURE_H
#define UTILITY_FEATURE_H

#if __cplusplus < 201100
#error "C++11 or better is required"
#endif

#ifdef __has_include
#if __has_include(<version>)
#include <version>
#endif
#endif

#define COMPILER_VALUE(value) (#value)

#ifdef __has_cpp_attribute
#define COMPILER_ATTRIBUTE_ENTRY(attr) \
    (#attr, COMPILER_VALUE(__has_cpp_attribute(attr)))
#else
#define __has_cpp_attribute(x) (0)
#define COMPILER_ATTRIBUTE_ENTRY(attr) (#attr, "_")
#endif

#if __has_cpp_attribute(fallthrough) >= 201603
#define FALLTHROUGH() [[fallthrough]]
#else
#ifdef __clang__
#define FALLTHROUGH() [[clang::fallthrough]]
#else
#define FALLTHROUGH()
#endif
#endif

#if __has_cpp_attribute(maybe_unused) >= 201603
#define MAYBE_UNUSED [[maybe_unused]]
#else
#ifdef __clang__
#define MAYBE_UNUSED [[maybe_unused]]
#else
#define MAYBE_UNUSED
#endif
#endif

#if __has_cpp_attribute(noreturn) >= 200809
#define NORETURN [[noreturn]]
#else
#ifdef __clang__
#define NORETURN [[noreturn]]
#else
#define NORETURN
#endif
#endif

// for global objects
#ifdef __clang__
#define NO_DESTROY [[clang::no_destroy]]
#else
#define NO_DESTROY
#endif

#endif